package cn.t.service.order;

import cn.t.constants.CommonConstants;
import cn.t.constants.ResponseError;
import cn.t.core.exception.BizException;
import cn.t.core.service.ServiceImpl;
import cn.t.dto.order.repenlement.ReplenishmentDetailSkuDTO;
import cn.t.dto.order.repenlement.ReplenishmentInfoDTO;
import cn.t.dto.order.repenlement.ReplenishmentQueryRequest;
import cn.t.enums.order.ReplenishmentStatusEnum;
import cn.t.model.device.DeviceDO;
import cn.t.model.order.ReplenishmentDO;
import cn.t.model.order.ReplenishmentDetailDO;
import cn.t.repository.order.ReplenishmentRepository;
import cn.t.utils.DateUtil;
import cn.t.utils.MsvmUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;

/**
 * 补货订单表(Replenishment)领域服务
 *
 * @author t
 * @since 2024-05-24 10:19:12
 */
@Slf4j
@Service
@AllArgsConstructor
public class ReplenishmentService extends ServiceImpl<ReplenishmentDO, ReplenishmentRepository> {

    public void updateReplenishmentByVO(  ReplenishmentDO replenishmentDO) {
        repository.updateReplenishment(replenishmentDO);
    }

    public ReplenishmentInfoDTO replenishmentDetailGroupSku(List<String> rsSn) {
        //获取补货信息
        ReplenishmentDO replenishmentDO = new ReplenishmentDO();
        replenishmentDO.setRsSnList(rsSn);
        List<ReplenishmentDO> repositoryList = repository.findByModel(replenishmentDO, CommonConstants.ZERO, Integer.MAX_VALUE, null, null);
        if (CollectionUtils.isEmpty(repositoryList)){
            throw new BizException(ResponseError.DATA_NOTFOUND_ERR,ResponseError.DATA_NOTFOUND_ERR.getName());
        }
        //判断 replenishments 的是否同一客户
        if (repositoryList.stream().map(ReplenishmentDO::getFirmId).distinct().count() > 1) {
            throw new BizException(ResponseError.DATA_ERR,"请选择同一公司补货单下单");
        }
        //获取校验补货单状态  非待补货
        if (repositoryList.stream().anyMatch(replenishmentVo-> !replenishmentVo.getRsStatus().equals(ReplenishmentStatusEnum.PENDING.getCode()))) {
            throw new BizException(ResponseError.DATA_ERR,"选择的补货单为非待补货状态，无法下单");
        }
        List<ReplenishmentDetailSkuDTO> list =  replenishmentDetailSkuDimension(rsSn);
        ReplenishmentInfoDTO replenishmentInfoDTO = new ReplenishmentInfoDTO();
        replenishmentInfoDTO.setFirmId(repositoryList.stream().findFirst().get().getFirmId());
        replenishmentInfoDTO.setDetails(list);
        return replenishmentInfoDTO;
    }

    public List<ReplenishmentDetailSkuDTO> replenishmentDetailSkuDimension(  List<String>  rsSnList) {
        //获取行信息
        ReplenishmentDetailDO replenishmentDO = new ReplenishmentDetailDO();
        replenishmentDO.setRsSnList(rsSnList);
        List<ReplenishmentDetailDO> repositoryList = replenishmentDetailService.findByModel(replenishmentDO, CommonConstants.ZERO, Integer.MAX_VALUE, null, null);
        Map<String, ReplenishmentDetailDO> replenishmentDetailMap = repositoryList.stream().collect(Collectors.toMap(ReplenishmentDetailDO::getSkuCode,
                replenishmentDetailDO -> replenishmentDetailDO, getRsSumQty()));
        List<ReplenishmentDetailDO> replenishmentDetailList = new ArrayList<>(replenishmentDetailMap.values());
        return    replenishmentDetailList.stream().map(replenishmentDetailDTO -> {
            ReplenishmentDetailSkuDTO replenishmentDetailSkuDimensionDetailDTO = new ReplenishmentDetailSkuDTO();
            replenishmentDetailSkuDimensionDetailDTO.setSkuName(replenishmentDetailDTO.getSkuName());
            replenishmentDetailSkuDimensionDetailDTO.setSkuCode(replenishmentDetailDTO.getSkuCode());
            replenishmentDetailSkuDimensionDetailDTO.setRsQty(replenishmentDetailDTO.getRsQty());
            replenishmentDetailSkuDimensionDetailDTO.setActualRsQty(replenishmentDetailDTO.getActualRsQty());
            return replenishmentDetailSkuDimensionDetailDTO;
        }).collect(Collectors.toList());
    }

    public String addReplenishment(DeviceDO deviceDO) {
        String rsOrderSn = MsvmUtil.getOrderSn(deviceDO.getId());
        ReplenishmentDO replenishmentDO = new ReplenishmentDO();


        replenishmentDO.setFirmId(deviceDO.getFirmId());
        replenishmentDO.setDeviceName(deviceDO.getDeviceName());
        replenishmentDO.setFirmId(deviceDO.getFirmId());
        replenishmentDO.setDeviceId(deviceDO.getId());
        replenishmentDO.setRsSn(rsOrderSn);
        repository.add(replenishmentDO);
        return rsOrderSn;
    }

    public List<ReplenishmentDO> queryList(ReplenishmentQueryRequest param, Integer pageNo, Integer pageSize) {
      ReplenishmentDO replenishmentDO = setParam(param);
    return repository.findByModel(replenishmentDO, pageNo, pageSize, "id", " desc");
    }

    public Long queryListCount(ReplenishmentQueryRequest param) {
        ReplenishmentDO replenishmentDO = setParam(param);
        return repository.count(replenishmentDO);
    }

    private static ReplenishmentDO setParam(ReplenishmentQueryRequest param) {
        ReplenishmentDO replenishmentDO = new ReplenishmentDO();
        if (param.getRsStatus() != null){
            replenishmentDO.setRsStatus(param.getRsStatus().getCode());
        }
        if (!ObjectUtils.isEmpty(param.getStatusList())){
            replenishmentDO.setRsStatusList(param.getStatusList());
        }
        replenishmentDO.setRsSn(param.getRsSn());
        replenishmentDO.setFirmId(param.getFirmId());
        replenishmentDO.setDeviceId(param.getDeviceId());
        replenishmentDO.setDeviceIds(param.getDeviceIds());
        replenishmentDO.setDeviceName(param.getDeviceName());
        replenishmentDO.setDeviceNameOrId(param.getDeviceNameOrId());
        replenishmentDO.setOrderNo(param.getOrderNo());
        replenishmentDO.setGmtCreatedStart(DateUtil.startDate(param.getGmtStart()));
        replenishmentDO.setGmtCreatedEnd(DateUtil.endDate(param.getGmtEnd()));
        return replenishmentDO;
    }

    private static BinaryOperator<ReplenishmentDetailDO> getRsSumQty() {
        return (k1, k2) -> {
            k1.setRsQty(k1.getRsQty() + k2.getRsQty());
            k1.setActualRsQty(k1.getActualRsQty() + k2.getActualRsQty());
            return k1;
        };
    }

    @Resource
    private ReplenishmentDetailService  replenishmentDetailService;

}
